#include "stdafx.h"
#include "ActiveObjectPortTestSuite.h"

namespace CO { namespace SpiFoundation { namespace RoomFW {

bool TestProtocol::validMessage(MessageID messageID, const IPayloadSP& payload) const
{
	bool retVal = false;
	if (0 == payload)
	{
		// In
		if (!this->isConjugate())
		{
			switch (messageID)
			{
			case TEST00:
			case TEST01:
			case TEST02:
			case TEST03:
			case TEST04:
			case TEST05:
			case TEST06:
			case TEST11:
			case TEST1B:
			case TESTB1:
			case TESTBB:
				retVal = true;
			}
		}
		// Out
		else
		{
			switch (messageID)
			{
			case PASS:
			case FAIL:
				retVal = true;
			}
		}
	}
	return retVal;
}

const char* TestProtocol::messageName(MessageID messageID) const
{
	switch (messageID)
	{
	case TEST00:
		return "TEST00";
	case TEST01:
		return "TEST01";
	case TEST02:
		return "TEST02";
	case TEST03:
		return "TEST03";
	case TEST04:
		return "TEST04";
	case TEST05:
		return "TEST05";
	case TEST06:
		return "TEST06";
	case TEST11:
		return "TEST11";
	case TEST1B:
		return "TEST1B";
	case TESTB1:
		return "TESTB1";
	case TESTBB:
		return "TESTBB";
	case PASS:
		return "PASS";
	case FAIL:
		return "FAIL";
	}
	return "***UNKNOWN***";
}

const ActiveObject::PortPriority FrontObject::PortPriorities[] = {PRI_NORMAL, PRI_NORMAL, PRI_NORMAL, PRI_NORMAL};
const size_t FrontObject::PortPrioritiesSize = sizeof(FrontObject::PortPriorities) / sizeof(ActiveObject::PortPriority);

FrontObject::FrontObject(void) :
	ActiveObject(PORT_COUNT, ActiveObject::PortPriorityArray(&PortPriorities[0], &PortPriorities[PortPrioritiesSize])),
	testProtocol_(false),
	testProtocolStar_(true),
	testCase_(TestProtocol::FAIL),
	pass1_(false),
	pass2_(false),
	timerId_(RoomTimer::InvalidTimerId),
	timeout_(0, 200000000)
{
}

FrontObject::~FrontObject(void)
{
}

void FrontObject::reset(void)
{
	ASSERT(!this->isRunning());
	testCase_ = TestProtocol::FAIL;
	pass1_ = false;
	pass2_ = false;
	timerId_ = RoomTimer::InvalidTimerId;
}

IContractCheckerSPC FrontObject::getContractChecker(PortIndex portIndex) const
{
	switch (portIndex.port())
	{
	case PORT_FRONT:
		return IContractCheckerSPC(&testProtocol_, NullDeleter<const TestProtocol>());
	case PORT_BACK1:
	case PORT_BACK2:
		return IContractCheckerSPC(&testProtocolStar_, NullDeleter<const TestProtocol>());
	default:
		ASSERT(false);
	}
	return IContractCheckerSPC(); // To quiet the compiler.
}

const char* FrontObject::getPortName(size_t portIndex) const
{
	switch (portIndex)
	{
	case PORT_FRONT:
		return "PORT_FRONT";
	case PORT_BACK1:
		return "PORT_BACK1";
	case PORT_BACK2:
		return "PORT_BACK2";
	case PORT_COUNT:
		return "PORT_TIMER";
	};
	return "***UNKNOWN***";
}

void FrontObject::handle(RoomMessageSP message)
{
	try
	{
		switch (message->portIndex().port())
		{
		case PORT_FRONT:
			{
				switch (message->messageID())
				{
				case TestProtocol::TEST00:
					{
						TestProtocol::MessageIds result = TestProtocol::FAIL;
						// Check port front is bound and backs are not.
						if (this->isBound(PORT_FRONT) && 
							(this->replicationCount(PORT_FRONT) == 2) &&
							!this->isBound(PortIndex(PORT_FRONT, 0)) && 
							this->isBound(PortIndex(PORT_FRONT, 1)) && 
							!this->isBound(PortIndex(PORT_FRONT, 2)) && 
							this->isBound(PortIndex(PORT_FRONT, 3)) && 
							!this->isBound(PORT_BACK1) &&
							(this->replicationCount(PORT_BACK1) == 0) &&
							!this->isBound(PortIndex(PORT_BACK1, 0)) &&
							!this->isBound(PortIndex(PORT_BACK1, 1)) &&
							!this->isBound(PortIndex(PORT_BACK2)) &&
							(this->replicationCount(PORT_BACK2) == 0) &&
							!this->isBound(PortIndex(PORT_BACK2, 0)) &&
							!this->isBound(PortIndex(PORT_BACK2, 1)))
						{
							result = TestProtocol::PASS;
						}
						// Iterate through each binding.
						PortIndex dest = this->getFirstBound(PORT_FRONT);
						do
						{
							this->sendMessage(dest, result);
						} while (this->getNextBound(dest));
					}
					break;
				case TestProtocol::TEST01:
				case TestProtocol::TEST03:
					message->reply(TestProtocol::PASS);
					break;
				case TestProtocol::TEST02:
					{
						testCase_ = static_cast<TestProtocol::MessageIds>(message->messageID());
						this->sendMessage(PortIndex(PORT_BACK1, 0), message->messageID());
						timerId_ = this->setTimer(timeout_);
					}
					break;
				case TestProtocol::TEST05:
				case TestProtocol::TEST06:
					{
						RoomMessageSP reply = 
							this->invoke(1000, PortIndex(PORT_BACK1, 0), message->messageID(), IPayloadSP(), false);
						TestProtocol::MessageIds result = TestProtocol::FAIL;
						if ((0 != reply) && (TestProtocol::PASS == reply->messageID()))
						{
							result = TestProtocol::PASS;
						}
						this->sendMessage(PortIndex(PORT_FRONT, 0), result);
					}
					break;
				case TestProtocol::TEST04:
					break;
				case TestProtocol::TEST11:
				case TestProtocol::TEST1B:
					{
						testCase_ = static_cast<TestProtocol::MessageIds>(message->messageID());
						this->sendMessage(PortIndex(PORT_BACK1, 0), message->messageID());
						timerId_ = this->setTimer(timeout_);
					}
					break;
				case TestProtocol::TESTB1:
				case TestProtocol::TESTBB:
					{
						testCase_ = static_cast<TestProtocol::MessageIds>(message->messageID());
						this->sendMessage(PORT_BACK1, message->messageID());
						timerId_ = this->setTimer(timeout_);
					}
					break;
				default:
					ASSERT(FALSE); // Already handled all legal messages.  Anything else is an error!
				}
			}
			break;
		case PORT_BACK1:
			{
				switch (message->messageID())
				{
				case TestProtocol::PASS:
					{
						pass1_ = true;
					}
					break;
				case TestProtocol::FAIL:
					{
						pass1_ = false;
					}
					break;
				}
			}
			break;
		case PORT_BACK2:
			{
				switch (message->messageID())
				{
				case TestProtocol::PASS:
					{
						pass2_ = true;
					}
					break;
				case TestProtocol::FAIL:
					{
						pass2_ = false;
					}
					break;
				}
			}
			break;
		case PORT_COUNT: // Timer port index, case requires literal.
			{
				TestProtocol::MessageIds result = TestProtocol::FAIL;
				switch (testCase_)
				{
				case TestProtocol::TEST02:
				case TestProtocol::TEST11:
				case TestProtocol::TESTB1:
					if (pass1_ && !pass2_)
					{
						result = TestProtocol::PASS;
					}
					this->sendMessage(PortIndex(PORT_FRONT, 0), result);
					break;
				case TestProtocol::TEST1B:
				case TestProtocol::TESTBB:
					if (pass1_ && pass2_)
					{
						result = TestProtocol::PASS;
					}
					this->sendMessage(PORT_FRONT, result);
					break;
				}
			}
			break;
		default:
			ASSERT(FALSE); // No more ports!
		}
	}
	//
	// TODO: Catch specific errors and handle them correctly.
	//
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		// This error might have been thrown from outside this object.  Update before forwarding.
		e.setObjectName(this->getObjectName());
		G_LOG_2_ERROR("%s: %s", this->getObjectName(), e.what());
		ASSERT(false);
		throw;
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_2_ERROR("%s: %s", this->getObjectName(), e.what());
		ASSERT(false);
		throw;
	}
	catch (std::runtime_error& e)
	{
		G_LOG_2_ERROR("%s: %s", this->getObjectName(), e.what());
		ASSERT(false);
		throw;
	}
	catch (std::exception& e)
	{
		G_LOG_2_ERROR("%s: %s", this->getObjectName(), e.what());
		ASSERT(false);
		throw;
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_1_ERROR("%s: Unhandled Exception", this->getObjectName());
		ASSERT(false);
		throw;
	}
}

const ActiveObject::PortPriority BackObject::PortPriorities[] = {PRI_NORMAL, PRI_NORMAL, PRI_NORMAL};
const size_t BackObject::PortPrioritiesSize = sizeof(BackObject::PortPriorities) / sizeof(ActiveObject::PortPriority);

BackObject::BackObject(void) :
	ActiveObject(PORT_COUNT, ActiveObject::PortPriorityArray(&PortPriorities[0], &PortPriorities[PortPrioritiesSize])),
	testProtocol_(false),
	testCase_(TestProtocol::FAIL),
	pass1_(false),
	pass2_(false),
	timerId_(RoomTimer::InvalidTimerId),
	timeout_(0, 100000000)
{
}

BackObject::~BackObject(void)
{
}

void BackObject::reset(void)
{
	ASSERT(!this->isRunning());
	ASSERT(!this->isRunning());
	testCase_ = TestProtocol::FAIL;
	pass1_ = false;
	pass2_ = false;
	timerId_ = RoomTimer::InvalidTimerId;
}

IContractCheckerSPC BackObject::getContractChecker(PortIndex portIndex) const
{
	switch (portIndex.port())
	{
	case PORT_1:
	case PORT_2:
		return IContractCheckerSPC(&testProtocol_, NullDeleter<const TestProtocol>());
	default:
		ASSERT(false);
	}
	return IContractCheckerSPC(); // To quiet the compiler.
}

const char* BackObject::getPortName(size_t portIndex) const
{
	switch (portIndex)
	{
	case PORT_1:
		return "PORT_1";
	case PORT_2:
		return "PORT_2";
	case PORT_COUNT:
		return "PORT_TIMER";
	};
	return "***UNKNOWN***";
}

void BackObject::handle(RoomMessageSP message)
{
	switch (message->portIndex().port())
	{
	case PORT_1:
		{
			switch (message->messageID())
			{
			case TestProtocol::TEST02:
			case TestProtocol::TEST05:
				message->reply(TestProtocol::PASS);
				break;
			case TestProtocol::TEST06:
				break;
			case TestProtocol::TEST11:
			case TestProtocol::TEST1B:
			case TestProtocol::TESTB1:
			case TestProtocol::TESTBB:
				{
					testCase_ = static_cast<TestProtocol::MessageIds>(message->messageID());
					pass1_ = true;
					timerId_ = this->setTimer(timeout_);
				}
				break;
			default:
				ASSERT(FALSE); // Already handled all legal messages.  Anything else is an error!
			}
		}
		break;
	case PORT_2:
		{
			pass2_ = true;
		}
		break;
	case PORT_COUNT: // Timer port index, case requires literal.
		{
			TestProtocol::MessageIds result = TestProtocol::FAIL;
			switch (testCase_)
			{
			case TestProtocol::TEST02:
			case TestProtocol::TEST11:
			case TestProtocol::TEST1B:
				if (pass1_ && !pass2_)
				{
					result = TestProtocol::PASS;
				}
				break;
			case TestProtocol::TESTB1:
			case TestProtocol::TESTBB:
				if (pass1_ && pass2_)
				{
					result = TestProtocol::PASS;
				}
				break;
			}
			switch (testCase_)
			{
			case TestProtocol::TEST11:
			case TestProtocol::TESTB1:
				this->sendMessage(PortIndex(PORT_1, 0), result);
				break;
			case TestProtocol::TEST1B:
			case TestProtocol::TESTBB:
				this->sendMessage(PORT_1, result);
				break;
			}
		}
		break;
	default:
		ASSERT(FALSE); // No more ports!
	}
}

ActiveObjectPortTestSuite::ActiveObjectPortTestSuite(void) :
	portal1_("Portal_1"),
	portal2_("Portal_2"),
	frontObject_(),
	backObject_()
{
	// Add test cases.
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test00)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test01)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test02)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test03)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test04)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test05)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test06)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test11)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::test1B)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::testB1)
	LOG_TEST_ADD(ActiveObjectPortTestSuite::testBB)
	TEST_ASSERT(portal1_.initialize())
	TEST_ASSERT(portal2_.initialize())
}

ActiveObjectPortTestSuite::~ActiveObjectPortTestSuite(void)
{
}

void ActiveObjectPortTestSuite::setup()
{
	LoggedTestSuite::setup();

	// Start test objects.
	frontObject_.reset();
	backObject_.reset();
	try
	{
		::boost::shared_ptr<FrontObject> frontObject(&frontObject_, NullDeleter<FrontObject>());
		::boost::shared_ptr<BackObject> backObject(&backObject_, NullDeleter<BackObject>());
		::boost::shared_ptr<Portal> portal1(&portal1_, NullDeleter<Portal>());
		::boost::shared_ptr<Portal> portal2(&portal2_, NullDeleter<Portal>());
		bindings_.push_back(BindingSP(new PortalBinding(portal1, frontObject, FrontObject::PORT_FRONT)));
		bindings_.push_back(BindingSP(new PortalBinding(portal2, frontObject, FrontObject::PORT_FRONT)));
		bindings_.push_back(BindingSP(new ActiveObjectsBinding(frontObject, FrontObject::PORT_BACK1,
															   backObject, BackObject::PORT_1)));
		bindings_.push_back(BindingSP(new ActiveObjectsBinding(frontObject, FrontObject::PORT_BACK1,
															   backObject, BackObject::PORT_2)));
		bindings_.push_back(BindingSP(new ActiveObjectsBinding(frontObject, FrontObject::PORT_BACK2,
															   backObject, BackObject::PORT_1)));
		bindings_.push_back(BindingSP(new ActiveObjectsBinding(frontObject, FrontObject::PORT_BACK2,
															   backObject, BackObject::PORT_2)));
	}
	catch (std::runtime_error e)
	{
		TEST_ASSERT_MSG(false, e.what());
	}
	TEST_ASSERT(frontObject_.start(DWait));
	TEST_ASSERT(frontObject_.isRunning(DWait));
	TEST_ASSERT(backObject_.start(DWait));
	TEST_ASSERT(backObject_.isRunning(DWait));
}

void ActiveObjectPortTestSuite::tear_down()
{
	TEST_ASSERT(backObject_.stop(DWait));
	TEST_ASSERT(frontObject_.stop(DWait));
	bindings_.clear();
	TEST_ASSERT_MSG(!frontObject_.isErrored(), frontObject_.errorMessage().c_str());
	TEST_ASSERT_MSG(!backObject_.isErrored(), backObject_.errorMessage().c_str());
	LoggedTestSuite::tear_down();
}

void ActiveObjectPortTestSuite::test00(void)
{
	try
	{
		// Ignore members setup()
		EventPortalSP portal1(new EventPortal("portal1"));
		TEST_ASSERT(portal1->initialize());
		EventPortalSP portal2(new EventPortal("portal2"));
		TEST_ASSERT(portal2->initialize());
		IActiveObjectSP frontObject(new FrontObject());
		BindingList bindings;
		try
		{
			EventPortalSP tmpPortal1(new EventPortal("tmp portal1"));
			TEST_ASSERT(tmpPortal1->initialize());
			BindingSP tmp1(new PortalBinding(tmpPortal1, frontObject, FrontObject::PORT_FRONT));

			bindings.push_back(BindingSP(new PortalBinding(portal1, frontObject, FrontObject::PORT_FRONT)));
			
			EventPortalSP tmpPortal2(new EventPortal("tmp portal2"));
			TEST_ASSERT(tmpPortal2->initialize());
			BindingSP tmp2(new PortalBinding(tmpPortal2, frontObject, FrontObject::PORT_FRONT));

			bindings.push_back(BindingSP(new PortalBinding(portal2, frontObject, FrontObject::PORT_FRONT)));
		}
		catch (std::runtime_error e)
		{
			TEST_ASSERT_MSG(false, e.what());
		}
		TEST_ASSERT(frontObject->start(DWait));
		TEST_ASSERT(frontObject->isRunning(DWait));

		portal1->sendMessage(TestProtocol::TEST00);
		TEST_ASSERT(portal1->wait(DWait) && portal2->wait(DWait));
		RoomMessageSP message = portal1->getMessage();
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2->getMessage();
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		TEST_ASSERT(frontObject->stop(DWait));
		bindings.clear();
		TEST_ASSERT_MSG(!frontObject->isErrored(), frontObject->errorMessage().c_str());
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test01(void)
{
	try
	{
		portal1_.sendMessage(TestProtocol::TEST01);
		TEST_ASSERT(portal1_.wait(DWait) && !portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test02(void)
{
	try
	{
		portal1_.sendMessage(TestProtocol::TEST02);
		TEST_ASSERT(portal1_.wait(DWait) && !portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test03(void)
{
	try
	{
		RoomMessageSP message = portal1_.invoke(DWait, TestProtocol::TEST03, IPayloadSP(), false);
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test04(void)
{
	try
	{
		RoomMessageSP message = portal1_.invoke(DWait, TestProtocol::TEST04, IPayloadSP(), false);
		TEST_ASSERT(0 == message);
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test05(void)
{
	try
	{
		portal1_.sendMessage(TestProtocol::TEST05);
		TEST_ASSERT(portal1_.wait(DWait) && !portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test06(void)
{
	try
	{
		portal1_.sendMessage(TestProtocol::TEST06);
		TEST_ASSERT(portal1_.wait(DWait) && !portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::FAIL == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test11()
{
	try
	{
		portal1_.sendMessage(TestProtocol::TEST11);
		TEST_ASSERT(portal1_.wait(DWait) && !portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::test1B()
{
	try
	{
		portal1_.sendMessage(TestProtocol::TEST1B);
		TEST_ASSERT(portal1_.wait(DWait) && portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::testB1()
{
	try
	{
		portal1_.sendMessage(TestProtocol::TESTB1);
		TEST_ASSERT(portal1_.wait(DWait) && !portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 == message);
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}

void ActiveObjectPortTestSuite::testBB()
{
	try
	{
		portal1_.sendMessage(TestProtocol::TESTBB);
		TEST_ASSERT(portal1_.wait(DWait) && portal2_.wait(DWait));
		RoomMessageSP message = portal1_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
		message = portal2_.getMessage();
		TEST_ASSERT(0 != message);
		TEST_ASSERT(TestProtocol::PASS == message->messageID());
	}
	catch (SpiFoundation::RoomFW::SendMessageError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (SpiFoundation::ErrorHandling::IError& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::runtime_error& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (std::exception& e)
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, e.what());
		TEST_ASSERT_MSG(false, e.what());
	}
	catch (...) // You must enable SEH exceptions to catch hardware (e.g. memory access) errors.
	{
		G_LOG_0(SpiFoundation::RoomFW::LV_ERROR, "Unhandled Exception");
		TEST_ASSERT_MSG(false, "Unhandled Exception");
	}
}


}}}
